2 * Copyright (c) 2005 David Kocher. All rights reserved.
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * Bug fixes, suggestions and comments should be sent to:
16 * dkocher@cyberduck.ch
19 #include <CoreFoundation/CoreFoundation.h>
20 #include <CoreFoundation/CFPlugInCOM.h>
21 #include <CoreServices/CoreServices.h>
23 // -----------------------------------------------------------------------------
25 // -----------------------------------------------------------------------------
28 #define PLUGIN_ID "9187E6ED-3A06-4D80-9880-2DC715703869"
31 // Below is the generic glue code for all plug-ins.
33 // You should not have to modify this code aside from changing
34 // names if you decide to change the names defined in the Info.plist
38 // -----------------------------------------------------------------------------
40 // -----------------------------------------------------------------------------
42 // The import function to be implemented in GetMetadataForFile.c
43 Boolean
GetMetadataForFile(void *thisInterface
,
44 CFMutableDictionaryRef attributes
,
45 CFStringRef contentTypeUTI
,
46 CFStringRef pathToFile
);
48 // The layout for an instance of MetaDataImporterPlugIn
49 typedef struct __MetadataImporterPluginType
51 MDImporterInterfaceStruct
*conduitInterface
;
54 } MetadataImporterPluginType
;
56 // -----------------------------------------------------------------------------
58 // -----------------------------------------------------------------------------
59 // Forward declaration for the IUnknown implementation.
62 MetadataImporterPluginType
*AllocMetadataImporterPluginType(CFUUIDRef inFactoryID
);
63 void DeallocMetadataImporterPluginType(MetadataImporterPluginType
*thisInstance
);
64 HRESULT
MetadataImporterQueryInterface(void *thisInstance
,REFIID iid
,LPVOID
*ppv
);
65 void *MetadataImporterPluginFactory(CFAllocatorRef allocator
,CFUUIDRef typeID
);
66 ULONG
MetadataImporterPluginAddRef(void *thisInstance
);
67 ULONG
MetadataImporterPluginRelease(void *thisInstance
);
68 // -----------------------------------------------------------------------------
69 // testInterfaceFtbl definition
70 // -----------------------------------------------------------------------------
71 // The TestInterface function table.
74 static MDImporterInterfaceStruct testInterfaceFtbl
= {
76 MetadataImporterQueryInterface
,
77 MetadataImporterPluginAddRef
,
78 MetadataImporterPluginRelease
,
83 // -----------------------------------------------------------------------------
84 // AllocMetadataImporterPluginType
85 // -----------------------------------------------------------------------------
86 // Utility function that allocates a new instance.
87 // You can do some initial setup for the importer here if you wish
88 // like allocating globals etc...
90 MetadataImporterPluginType
*AllocMetadataImporterPluginType(CFUUIDRef inFactoryID
)
92 MetadataImporterPluginType
*theNewInstance
;
94 theNewInstance
= (MetadataImporterPluginType
*)malloc(sizeof(MetadataImporterPluginType
));
95 memset(theNewInstance
,0,sizeof(MetadataImporterPluginType
));
97 /* Point to the function table */
98 theNewInstance
->conduitInterface
= &testInterfaceFtbl
;
100 /* Retain and keep an open instance refcount for each factory. */
101 theNewInstance
->factoryID
= CFRetain(inFactoryID
);
102 CFPlugInAddInstanceForFactory(inFactoryID
);
104 /* This function returns the IUnknown interface so set the refCount to one. */
105 theNewInstance
->refCount
= 1;
106 return theNewInstance
;
109 // -----------------------------------------------------------------------------
110 // DeallocCyberduck_Spotlight_ImporterMDImporterPluginType
111 // -----------------------------------------------------------------------------
112 // Utility function that deallocates the instance when
113 // the refCount goes to zero.
114 // In the current implementation importer interfaces are never deallocated
115 // but implement this as this might change in the future
117 void DeallocMetadataImporterPluginType(MetadataImporterPluginType
*thisInstance
)
119 CFUUIDRef theFactoryID
;
121 theFactoryID
= thisInstance
->factoryID
;
124 CFPlugInRemoveInstanceForFactory(theFactoryID
);
125 CFRelease(theFactoryID
);
129 // -----------------------------------------------------------------------------
130 // MetadataImporterQueryInterface
131 // -----------------------------------------------------------------------------
132 // Implementation of the IUnknown QueryInterface function.
134 HRESULT
MetadataImporterQueryInterface(void *thisInstance
,REFIID iid
,LPVOID
*ppv
)
136 CFUUIDRef interfaceID
;
138 interfaceID
= CFUUIDCreateFromUUIDBytes(kCFAllocatorDefault
,iid
);
140 if (CFEqual(interfaceID
,kMDImporterInterfaceID
)){
141 /* If the Right interface was requested, bump the ref count,
142 * set the ppv parameter equal to the instance, and
143 * return good status.
145 ((MetadataImporterPluginType
*)thisInstance
)->conduitInterface
->AddRef(thisInstance
);
147 CFRelease(interfaceID
);
150 if (CFEqual(interfaceID
,IUnknownUUID
)){
151 /* If the IUnknown interface was requested, same as above. */
152 ((MetadataImporterPluginType
*)thisInstance
)->conduitInterface
->AddRef(thisInstance
);
154 CFRelease(interfaceID
);
157 /* Requested interface unknown, bail with error. */
159 CFRelease(interfaceID
);
160 return E_NOINTERFACE
;
165 // -----------------------------------------------------------------------------
166 // MetadataImporterPluginAddRef
167 // -----------------------------------------------------------------------------
168 // Implementation of reference counting for this type. Whenever an interface
169 // is requested, bump the refCount for the instance. NOTE: returning the
170 // refcount is a convention but is not required so don't rely on it.
172 ULONG
MetadataImporterPluginAddRef(void *thisInstance
)
174 ((MetadataImporterPluginType
*)thisInstance
)->refCount
+= 1;
175 return ((MetadataImporterPluginType
*) thisInstance
)->refCount
;
178 // -----------------------------------------------------------------------------
179 // SampleCMPluginRelease
180 // -----------------------------------------------------------------------------
181 // When an interface is released, decrement the refCount.
182 // If the refCount goes to zero, deallocate the instance.
184 ULONG
MetadataImporterPluginRelease(void *thisInstance
)
186 ((MetadataImporterPluginType
*)thisInstance
)->refCount
-= 1;
187 if (((MetadataImporterPluginType
*)thisInstance
)->refCount
== 0){
188 DeallocMetadataImporterPluginType((MetadataImporterPluginType
*)thisInstance
);
191 return ((MetadataImporterPluginType
*) thisInstance
)->refCount
;
195 // -----------------------------------------------------------------------------
196 // Cyberduck_Spotlight_ImporterMDImporterPluginFactory
197 // -----------------------------------------------------------------------------
198 // Implementation of the factory function for this type.
200 void *MetadataImporterPluginFactory(CFAllocatorRef allocator
,CFUUIDRef typeID
)
202 MetadataImporterPluginType
*result
;
205 /* If correct type is being requested, allocate an
206 * instance of TestType and return the IUnknown interface.
208 if (CFEqual(typeID
,kMDImporterTypeID
)){
209 uuid
= CFUUIDCreateFromString(kCFAllocatorDefault
,CFSTR(PLUGIN_ID
));
210 result
= AllocMetadataImporterPluginType(uuid
);
214 /* If the requested type is incorrect, return NULL. */